/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: SpeedCtrlData.hpp,v 1.18 2009-07-22 14:49:14 morsko Exp $
 *
 * \file
 * \brief MaCI - SpeedCtrl Data parser header
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#ifndef _MACI_INTERFACE_SPEEDCTRLDATA_HPP_
#define _MACI_INTERFACE_SPEEDCTRLDATA_HPP_

#include "SpeedCtrlTypes.hpp"
#include "timestamp.hpp"
#include "MaCIData.hpp"
#include <stdio.h>
#include <vector>

namespace gim {
  namespace binbag{class CBinBag;}
}

namespace MaCI {
  namespace SpeedCtrl {


    /** SpeedCtrl Data Decoder/Encoder.
     * This class implements 
     *
     */
    class CSpeedCtrlData : public CMaCIData
    {
    public:
      /** Constructor.
       *
       */
      CSpeedCtrlData(void);


      /** Destructor.
       *
       */
      ~CSpeedCtrlData(void);
      

      /** Copy constructor for SpeedCtrlData. 
       *
       * The copy constructor duplicates the input object to maximum
       * depth (All containers are duplicated too). After a copy is
       * constructed, no dependencies to original Data element exist.
       *
       * @param[in] aSpeedCtrlData Reference to CSpeedCtrlData 
       *            container to copy.
       */
      CSpeedCtrlData(const CSpeedCtrlData &aSpeedCtrlData);

      

      /** Assignment operator for SpeedCtrlData.
       *
       * The assignment operator duplicates the input object to
       * maximum depth (All containers are duplicated too). After a
       * copy is constructed, no dependencies to original Data element
       * exist.
       *
       * @param[in] aSpeedCtrlData Reference to CSpeedCtrlData 
       *            container to copy.
       */
      CSpeedCtrlData &operator=(const CSpeedCtrlData &aSpeedCtrlData);



      ///////////////////////////////////////////////////
      // Derived from 'CMaCIData', see description there.
      bool DecodeFrom(gim::binbag::CBinBag *aBinBag = NULL);
      void Reset();
      void Print(const int level) const;
      ///////////////////////////////////////////////////


      // Setter ocmmands
      /** Set Timestamp element.
       * 
       * \see Common::TTimestamp
       *
       * @param[in] aStamp      Timestamp element to set.
       * @return                'true' if no such element previously
       *                        exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetTimestamp(const Common::TTimestamp &aStamp);


      /** Set Command element.
       *
       * Command elements must be accompanied by related dataelement
       * when required by commandtype. See the command enumerations
       * for a note about required datatype. (For example, 'SetSpeed'
       * command required a 'Speed' datatype after the command.
       * 
       * \see TCommand
       *
       * @param[in] aCmd        Command element to set.
       * @return                'true' if no such element previously
       *                        exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetCommand(const TCommand &aCmd);


      /** Set Speed element.
       * 
       * \see TSpeed
       *
       * @param[in] aSpeed      Speed element to set.
       * @return                'true' if no such element previously
       *                        exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetSpeed(const TSpeed &aSpeed);

      /** Set Command Intervals.
       * 
       * \see TCommandIntervals
       *
       * @param[in] aCommandIntervals      CommandIntervals element to set.
       * @return                           'true' if no such element previously
       *                                    exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetCommandIntervals(const TCommandIntervals &aCommandIntervals);


      /** Sets speed limits
       *
       * \see TSpeed
       *
       * @param[in] aMaxSpeeds  Maximum speeds to set.
       * @param[in] aMinSpeeds  Minimum speeds to set.
       * @return                'true' if no such element previously
       *                        exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetSpeedLimits(const TSpeed &aMaxSpeeds, const TSpeed &aMinSpeeds);

      /** Set timeout time- struct
       *
       * \see TTimeoutTime
       *
       * @param[in] aTimeoutTime Timeout time to set.
       * @return                'true' if no such element previously
       *                        exists, and a valid binbag::CBinBag backend exists.
       */
      bool SetTimeoutTime(const TTimeoutTime &aTimeoutTime);

      // Getter commands
      /** Get pointer to Common::TTimestamp element (if such exists).
       *
       * \see Common::TTimestamp
       * 
       * @return                Constant pointer to timestamp
       *                        element if such element exists
       *                        in the container. If the element 
       *                        doesn't exist, NULL is returned.
       */
      const Common::TTimestamp *GetTimestamp(void) const;

      
      /** Get constant pointer to TCommand element (if such exists).
       *
       * \see TCommand
       * 
       * @return                Constant pointer to command
       *                        element if such element exists
       *                        in the container. If the element 
       *                        doesn't exist, NULL is returned.
       */
      const TCommand *GetCommand(void) const;

      
      /** Get constant pointer to TSpeed element (if such exists).
       *
       * \see TSpeed
       * 
       * @return                Constant pointer to speed
       *                        element if such element exists
       *                        in the container. If the element 
       *                        doesn't exist, NULL is returned.
       */
      const TSpeed *GetSpeed(void) const;

      /** Get constant pointer to TCommandIntervals element (if such exists).
       *
       * \see TCommandIntervals
       * 
       * @return                Constant pointer to command interval
       *                        element if such element exists
       *                        in the container. If the element 
       *                        doesn't exist, NULL is returned.
       */
      const TCommandIntervals *GetCommandIntervals(void) const;

      /** Get constant pointer to maximum speed element (if such exists).
       *
       *
       * @return                Constant pointer to Speed elements if
       *                        such exists in the container. If the element
       *                        doesn't exist, NULL is returned.
       */
      const TSpeed *GetMaxSpeedLimit(void) const;

      /** Get constant pointer to maximum speed element (if such exists).
       *
       *
       * @return                Constant pointer to Speed elements if
       *                        such exists in the container. If the element
       *                        doesn't exist, NULL is returned.
       */
      const TSpeed *GetMinSpeedLimit(void) const;

      /** Get constant pointer to timeout time element (if such exists).
       *
       *
       * @return                Constant pointer to Timeout time elements if
       *                        such exists in the container. If the element
       *                        doesn't exist, NULL is returned.
       */
      const TTimeoutTime *GetTimeoutTime(void) const;
    private:
      bool iValid;
      bool iMaxSpeedLimitSet;      
      bool iMinSpeedLimitSet;      
      const Common::TTimestamp *iTimestampPtr; ///< Pointer to Timestamp
      const TCommand *iCommandPtr; ///< Pointer to command if any.
      const TSpeed *iSpeedPtr; ///< Pointer to speed
      const TSpeed *iSpeedLimitsPtr; ///<Pointer to speedLimits (Contains two TSpeed containers)
      const TCommandIntervals *iCommandIntervalsPtr; ///< Pointer to command intervals
      const TTimeoutTime * iTimeoutTimePtr; ///< Pointer to timeout time

    };
  }
}
#endif //_MACI_INTERFACE_SPEEDCTRLDATA_HPP_
